package com.coder.rental.controller;


import cn.hutool.core.convert.NumberWithFormat;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWTPayload;
import com.coder.rental.entity.Permission;
import com.coder.rental.entity.User;
import com.coder.rental.utils.RouteTreeUtils;
import com.coder.rental.vo.RouteVO;
import com.coder.rental.vo.UserInfoVo;
import com.coder.rental.service.IUserService;
import com.coder.rental.utils.JwtUtils;
import com.coder.rental.utils.RedisUtils;
import com.coder.rental.utils.Result;
import com.coder.rental.vo.TokenVo;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


@RestController
@RequestMapping("/rental/auth")
public class AuthController {
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private IUserService userService;




    /**
     * 使得用户接入到这个网址后可以直接在redis中删除原来的token,
     * 并将剩余时间赋予到一个新的token中，将其存到redis中，并返回
     */
    @PostMapping("/refreshToken")
    public Result refreshToken(HttpServletRequest request){
        String token = request.getHeader("token");
        if (StrUtil.isEmpty(token)){
            token=request.getParameter("token");
        }
        //获取用户名
        String username = (String) JwtUtils.parseToken(token).getClaim("username");
        //生成token
        Map map=new HashMap();
        map.put("username",username);
        String newToken = JwtUtils.createToken(map);
        //获取过期时间
        NumberWithFormat claim= (NumberWithFormat)
                JwtUtils.parseToken(newToken).getClaim(JWTPayload.EXPIRES_AT);
        DateTime dateTime = (DateTime) claim.convert(DateTime.class, claim);
        long expireTime=dateTime.getTime();
        //redis删除旧token操作
        String oldTokenKey="token:"+token;
        redisUtils.del(oldTokenKey);
        //redis添加新token操作
        long nowTime=DateTime.now().getTime();
        String newTokenKey="token:"+newToken;
        redisUtils.set(newTokenKey,newToken,(expireTime-nowTime)/1000);
        //封装到TokenVo里
        TokenVo tokenVo=new TokenVo();
        tokenVo.setToken(newToken);
        tokenVo.setExpireTime(expireTime);
        //返回结果
        return Result.success(tokenVo).setMessage("刷新token成功");
    }




    /**
     * 获取当前用户的信息
     *
     * 该接口不需要参数，通过SecurityContextHolder上下文获取认证信息。
     * 如果认证信息存在，则根据用户ID查询用户角色，并将用户基本信息和角色信息封装成
     UserInfoVo返回。
     * 如果认证信息不存在，则返回失败结果，提示认证信息为空。
     *
     * @return Result 包含用户信息的Result对象，如果获取失败则包含错误信息
     */
    @GetMapping("/info")
    public Result getUserInfo(){
        //获取保存在SecurityContextHolder里的User
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication==null){
            return Result.error().setMessage("认证信息为空");
        }
        User user = (User) authentication.getPrincipal();
        //获取保存的用户详细信息
        Integer id= user.getId();
        String introduction= user.getNickname();
        String name= user.getUsername();
        String avatar = user.getAvatar();
        List<String> roles= userService.getRolesByUserId(id);
        //封装进userInfoVo里面，并返回
        UserInfoVo userInfoVo=new UserInfoVo(id,name,avatar,introduction,roles);
        return Result.success(userInfoVo).setMessage("获取用户信息成功");
    }

    /**
     * 获取当前用户可操作的列表
     * @return
     */
    @GetMapping("/menuList")
    public Result getMenuList(){

        //从SecurityContextHolder获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            return Result.error().setMessage("认证信息为空");
        }
        User user = (User) authentication.getPrincipal();
        List<Permission> permissionList = user.getPermissionList();
        //将permission_type为2的按钮移除，不需要生成对应的菜单
        permissionList.removeIf(permission -> permission.getPermissionType() == 2);
        List<RouteVO> routeList = RouteTreeUtils.buildRouteTree(permissionList, 0);
        return Result.success(routeList).setMessage("获取菜单列表成功");


    }



}
